package com.mask.im.business.handler;

import cn.hutool.crypto.SecureUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;

/**
 * 加密服务
 * 提供统一的加密解密功能
 * 
 * @author jian
 */
@Log4j2
@Service
public class CryptoService {

    // 加密算法常量
    private static final String AES_ALGORITHM = "AES";
    private static final String DEFAULT_CHARSET = "UTF-8";

    /**
     * 加密字符串
     * 
     * @param plainText 明文
     * @param key 密钥
     * @param charset 字符集
     * @return 加密后的字符串
     */
    public String encrypt(String plainText, String key, String charset) {
        try {
            if (plainText == null || plainText.trim().isEmpty()) {
                log.warn("明文为空，跳过加密");
                return plainText;
            }
            
            if (key == null || key.trim().isEmpty()) {
                throw new IllegalArgumentException("加密密钥不能为空");
            }
            
            log.debug("开始加密，明文长度: {} bytes", plainText.length());
            
            // 使用AES加密
            String encryptedText = SecureUtil.aes(key.getBytes(charset)).encryptBase64(plainText);
            
            log.debug("加密完成，密文长度: {} bytes", encryptedText.length());
            
            return encryptedText;
            
        } catch (Exception e) {
            log.error("加密失败", e);
            throw new RuntimeException("加密失败: " + e.getMessage(), e);
        }
    }

    /**
     * 解密字符串
     * 
     * @param encryptedText 密文
     * @param key 密钥
     * @param charset 字符集
     * @return 解密后的字节数组
     */
    public byte[] decrypt(String encryptedText, String key, String charset) {
        try {
            if (encryptedText == null || encryptedText.trim().isEmpty()) {
                log.warn("密文为空，跳过解密");
                return new byte[0];
            }
            
            if (key == null || key.trim().isEmpty()) {
                throw new IllegalArgumentException("解密密钥不能为空");
            }
            
            log.debug("开始解密，密文长度: {} bytes", encryptedText.length());
            
            // 使用AES解密
            byte[] decryptedBytes = SecureUtil.aes(key.getBytes(charset)).decrypt(encryptedText);
            
            log.debug("解密完成，明文长度: {} bytes", decryptedBytes.length);
            
            return decryptedBytes;
            
        } catch (Exception e) {
            log.error("解密失败", e);
            throw new RuntimeException("解密失败: " + e.getMessage(), e);
        }
    }

    /**
     * 解密字符串为明文
     * 
     * @param encryptedText 密文
     * @param key 密钥
     * @param charset 字符集
     * @return 解密后的明文
     */
    public String decryptToString(String encryptedText, String key, String charset) {
        try {
            byte[] decryptedBytes = decrypt(encryptedText, key, charset);
            return new String(decryptedBytes, charset);
        } catch (Exception e) {
            log.error("解密为字符串失败", e);
            throw new RuntimeException("解密为字符串失败: " + e.getMessage(), e);
        }
    }

    /**
     * 使用默认字符集加密
     */
    public String encrypt(String plainText, String key) {
        return encrypt(plainText, key, DEFAULT_CHARSET);
    }

    /**
     * 使用默认字符集解密
     */
    public byte[] decrypt(String encryptedText, String key) {
        return decrypt(encryptedText, key, DEFAULT_CHARSET);
    }

    /**
     * 使用默认字符集解密为字符串
     */
    public String decryptToString(String encryptedText, String key) {
        return decryptToString(encryptedText, key, DEFAULT_CHARSET);
    }

    /**
     * 验证密钥格式
     * 
     * @param key 密钥
     * @return 是否有效
     */
    public boolean isValidKey(String key) {
        if (key == null || key.trim().isEmpty()) {
            return false;
        }
        
        // AES密钥长度检查（16, 24, 32字节）
        int keyLength = key.getBytes(StandardCharsets.UTF_8).length;
        return keyLength == 16 || keyLength == 24 || keyLength == 32;
    }

    /**
     * 生成随机密钥
     * 
     * @param keyLength 密钥长度（16, 24, 32）
     * @return 随机密钥
     */
    public String generateRandomKey(int keyLength) {
        if (keyLength != 16 && keyLength != 24 && keyLength != 32) {
            throw new IllegalArgumentException("密钥长度必须是16、24或32字节");
        }
        
        byte[] keyBytes = SecureUtil.generateKey(AES_ALGORITHM, keyLength).getEncoded();
        return new String(keyBytes, StandardCharsets.UTF_8);
    }
}
